package tms.presentation.bean.logging;

import tms.util.constants.RequestParameter;
import tms.util.context.ApplicationContext;
import tms.util.jsf.FacesContextManager;
import tms.util.localization.LocalizationManager;
import tms.util.logging.AreaType;
import tms.util.logging.Logger;

import javax.annotation.PostConstruct;
import javax.enterprise.context.RequestScoped;
import javax.inject.Inject;
import javax.inject.Named;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Named
@RequestScoped
public class LoggingViewBean {
    @Inject
    Logger logger;
    @Inject
    FacesContextManager facesContextManager;
    @Inject
    LocalizationManager localizationManager;

    private List<String> areas;
    private String selectedArea;
    private Map<String, Boolean> logAvailable;

    public List<String> getAreas() {
        if (areas == null) {
            areas = new ArrayList<String>();
            for (AreaType areaType : AreaType.values()) {
                areas.add(areaType.name());
            }
        }
        return areas;
    }

    public Map<String, Boolean> getLogAvailable() {
        return logAvailable;
    }

    public String getSelectedArea() {
        return selectedArea;
    }

    public void setSelectedArea(String selectedArea) {
        this.selectedArea = selectedArea;
    }

    public void uploadLogFile() {
        String area = facesContextManager.getRequestParameter(RequestParameter.LOG_AREA);
        File file = new File(getLogFilePath(area));
        if (file.exists()) {
            try {
                HttpServletResponse response = (HttpServletResponse)facesContextManager.getExternalContext().getResponse();
                response.setContentType("application/force-download");
                response.addHeader("Content-Disposition", "attachment; filename=\"" + getLogFileName(area) + "\"");
                byte[] buf = new byte[1024];
                long length = file.length();
                BufferedInputStream in = new BufferedInputStream(new FileInputStream(file));
                ServletOutputStream out = response.getOutputStream();
                response.setContentLength((int)length);
                while ((in != null) && ((length = in.read(buf)) != -1)) {
                    out.write(buf, 0, (int)length);
                }
                in.close();
                out.close();
                facesContextManager.getFacesContext().responseComplete();
            } catch (IOException e) {
                logger.warning("Error reading from log file {0}", e, getLogFileName(area));
            }
        }
    }

    @PostConstruct
    private void init() {
        logAvailable = new HashMap<String, Boolean>();
        File file = null;
        for (AreaType areaType : AreaType.values()) {
            file = new File(getLogFilePath(areaType.name()));
            logAvailable.put(areaType.name(), file.exists());
        }
    }


    private String getLogFilePath(String area) {
        return ApplicationContext.getLoggingConfig().getDirectory() + getLogFileName(area);
    }

    private String getLogFileName(String area) {
        return MessageFormat.format(ApplicationContext.getLoggingConfig().getFileNamePattern(), area.toLowerCase());
    }
}
